package com.xh3140.xwidget.dialog;


import android.content.Context;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.Size;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.MutableLiveData;

import com.xh3140.xwidget.dialog.callback.ConfigParamsCallback;
import com.xh3140.xwidget.dialog.callback.ConfigViewCallback;
import com.xh3140.xwidget.dialog.listener.OnClickButtonListener;
import com.xh3140.xwidget.dialog.listener.OnCreatedViewListener;
import com.xh3140.xwidget.dialog.params.ButtonParams;
import com.xh3140.xwidget.dialog.params.FooterParams;
import com.xh3140.xwidget.dialog.params.HeaderParams;
import com.xh3140.xwidget.dialog.params.SubtitleParams;
import com.xh3140.xwidget.dialog.params.TitleParams;
import com.xh3140.xwidget.dialog.view.ButtonView;
import com.xh3140.xwidget.dialog.view.FooterView;
import com.xh3140.xwidget.dialog.view.HeaderView;
import com.xh3140.xwidget.dialog.view.RootView;
import com.xh3140.xwidget.dialog.view.SubtitleView;
import com.xh3140.xwidget.dialog.view.TitleView;

/**
 * 基础对话框类
 */
@SuppressWarnings("unused")
public abstract class BaseDialog<V extends View> extends AbstractDialog<V> {
  protected HeaderParams mHeaderParams;
  protected FooterParams mFooterParams;
  private OnCreatedViewListener<RootView<V>> mOnCreatedRootViewListener;
  private OnCreatedViewListener<HeaderView> mOnCreatedHeadViewListener;
  private OnCreatedViewListener<V> mOnCreatedBodyViewListener;
  private OnCreatedViewListener<FooterView> mOnCreatedFootViewListener;

  public BaseDialog<V> setOnCreatedRootViewListener(@Nullable OnCreatedViewListener<RootView<V>> listener) {
    mOnCreatedRootViewListener = listener;
    return this;
  }

  public BaseDialog<V> setOnCreatedHeadViewListener(@Nullable OnCreatedViewListener<HeaderView> listener) {
    mOnCreatedHeadViewListener = listener;
    return this;
  }

  public BaseDialog<V> setOnCreatedBodyViewListener(@Nullable OnCreatedViewListener<V> listener) {
    mOnCreatedBodyViewListener = listener;
    return this;
  }

  public BaseDialog<V> setOnCreatedFootViewListener(@Nullable OnCreatedViewListener<FooterView> listener) {
    mOnCreatedFootViewListener = listener;
    return this;
  }

  @Override
  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // 视图创建回调，可以在这些回调里修改样式
    final RootView<V> rootView = requireRootView();
    if (mOnCreatedRootViewListener != null) {
      mOnCreatedRootViewListener.onCreatedView(rootView);
    }
    final HeaderView headerView = rootView.getHeaderView();
    if (headerView != null && mOnCreatedHeadViewListener != null) {
      mOnCreatedHeadViewListener.onCreatedView(headerView);
    }
    final V bodyView = rootView.getBodyView();
    if (bodyView != null && mOnCreatedBodyViewListener != null) {
      mOnCreatedBodyViewListener.onCreatedView(bodyView);
    }
    final FooterView footerView = rootView.getFooterView();
    if (footerView != null && mOnCreatedFootViewListener != null) {
      mOnCreatedFootViewListener.onCreatedView(footerView);
    }
  }

  /**
   * 数据状态保存
   * 由于屏幕方向旋转等情况会导致构建数据丢失，所以需要保存
   */
  protected static abstract class ViewModel extends AbstractDialog.ViewModel {
    private final MutableLiveData<HeaderParams> mHeaderParamsData = new MutableLiveData<>();
    private final MutableLiveData<FooterParams> mFooterParamsData = new MutableLiveData<>();

    protected void configBaseDialogParams(@NonNull final BaseDialog<?> dialog) {
      configAbstractDialogParams(dialog);
      if (dialog.mHeaderParams == null) {
        dialog.mHeaderParams = mHeaderParamsData.getValue();
      } else {
        mHeaderParamsData.postValue(dialog.mHeaderParams);
      }
      if (dialog.mFooterParams == null) {
        dialog.mFooterParams = mFooterParamsData.getValue();
      } else {
        mFooterParamsData.postValue(dialog.mFooterParams);
      }
    }
  }

  /**
   * 构建器
   * 配置基础对话框属性
   */
  public static abstract class Builder<D extends BaseDialog<?>, B extends Builder<D, B>> extends AbstractDialog.Builder<D, B> {
    protected final HeaderParams mHeaderParams;
    protected final FooterParams mFooterParams;
    protected OnClickButtonListener<D> mOnClickButtonListener;

    public Builder(@NonNull Context context) {
      super(context);
      mHeaderParams = new HeaderParams(context);
      mFooterParams = new FooterParams(context);
    }

    public Builder(@NonNull FragmentActivity activity) {
      super(activity);
      mHeaderParams = new HeaderParams(mDialogParams.context);
      mFooterParams = new FooterParams(mDialogParams.context);
    }

    public Builder(@NonNull Fragment fragment) {
      super(fragment);
      mHeaderParams = new HeaderParams(mDialogParams.context);
      mFooterParams = new FooterParams(mDialogParams.context);
    }

    /**
     * 转换为继承可用链式编程构建器
     *
     * @return 可以链式编程的构建器
     */
    @SuppressWarnings("unchecked")
    private B toBuilder() {
      return (B) this;
    }

    /**
     * 配置对话框首部视图标题视图属性
     *
     * @param callback 配置回调
     */
    public B configTitleParams(@NonNull ConfigParamsCallback<TitleParams> callback) {
      callback.callback(mHeaderParams.title);
      return toBuilder();
    }

    /**
     * 配置对话框首部视图副标题视图属性
     *
     * @param callback 配置回调
     */
    public B configSubtitleParams(@NonNull ConfigParamsCallback<SubtitleParams> callback) {
      callback.callback(mHeaderParams.subtitle);
      return toBuilder();
    }

    /**
     * 配置对话框底部视图消极按钮视图属性
     *
     * @param callback 配置回调
     */
    public B configNegativeButtonParams(@NonNull ConfigParamsCallback<ButtonParams> callback) {
      callback.callback(mFooterParams.negative);
      return toBuilder();
    }

    /**
     * 配置对话框底部视图积极按钮视图属性
     *
     * @param callback 配置回调
     */
    public B configPositiveButtonParams(@NonNull ConfigParamsCallback<ButtonParams> callback) {
      callback.callback(mFooterParams.positive);
      return toBuilder();
    }

    /**
     * 配置对话框底部视图中立按钮视图属性
     *
     * @param callback 配置回调
     */
    public B configNeutralButtonParams(@NonNull ConfigParamsCallback<ButtonParams> callback) {
      callback.callback(mFooterParams.neutral);
      return toBuilder();
    }

    //=============================================================================================//

    /**
     * 设置标题视图文本
     *
     * @param text 文本
     */
    public B setTitleText(@Nullable CharSequence text) {
      mHeaderParams.title.text = text;
      return toBuilder();
    }

    /**
     * 设置标题视图文本字体大小 sp
     *
     * @param textSize 字体大小
     */
    public B setTitleTextSize(float textSize) {
      mHeaderParams.title.textSize = textSize;
      return toBuilder();
    }

    /**
     * 设置标题视图文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setTitleTextColor(@ColorInt int textColor) {
      mHeaderParams.title.textColor = textColor;
      return toBuilder();
    }

    /**
     * 设置标题视图文本字体样式
     *
     * @param typeface 字体样式
     */
    public B setTitleTypeface(int typeface) {
      mHeaderParams.title.typeface = typeface;
      return toBuilder();
    }

    /**
     * 设置标题视图文本位置
     *
     * @param gravity 位置
     */
    public B setTitleGravity(int gravity) {
      mHeaderParams.title.gravity = gravity;
      return toBuilder();
    }

    /**
     * 设置标题视图背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setTitleBackgroundColor(@ColorInt int backgroundColor) {
      mHeaderParams.title.backgroundColor = backgroundColor;
      return toBuilder();
    }


    /**
     * 设置标题视图内边距
     * 格式：[start, top, end, bottom] px
     *
     * @param padding 边距
     */
    public B setTitlePadding(@Nullable @Size(4) int[] padding) {
      mHeaderParams.title.padding = padding;
      return toBuilder();
    }

    /**
     * 设置标题视图内边距
     *
     * @param padding 边距 px
     */
    public B setTitlePadding(@Px int padding) {
      return setTitlePadding(new int[]{padding, padding, padding, padding});
    }

    /**
     * 设置标题视图内边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public B setTitlePadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setTitlePadding(new int[]{left, top, right, bottom});
    }

    /**
     * 设置标题视图配置回调
     * 拥有绝对控制权的回调，它在其他属性配置结束后回调
     * 一般情况不要使用它，除非提供的现有配置属性不满足需求
     *
     * @param callback 配置回调
     */
    public B setTitleViewCallback(@Nullable ConfigViewCallback<TitleView> callback) {
      mHeaderParams.title.callback = callback;
      return toBuilder();
    }

    //=============================================================================================//

    /**
     * 设置副标题视图文本
     *
     * @param text 文本
     */
    public B setSubtitleText(@Nullable CharSequence text) {
      mHeaderParams.subtitle.text = text;
      return toBuilder();
    }

    /**
     * 设置副标题视图文本字体大小 sp
     *
     * @param textSize 字体大小
     */
    public B setSubtitleTextSize(float textSize) {
      mHeaderParams.subtitle.textSize = textSize;
      return toBuilder();
    }

    /**
     * 设置副标题视图文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setSubtitleTextColor(@ColorInt int textColor) {
      mHeaderParams.subtitle.textColor = textColor;
      return toBuilder();
    }

    /**
     * 设置副标题视图文本字体样式
     *
     * @param typeface 字体样式
     */
    public B setSubtitleTypeface(int typeface) {
      mHeaderParams.subtitle.typeface = typeface;
      return toBuilder();
    }

    /**
     * 设置副标题视图文本位置
     *
     * @param gravity 位置
     */
    public B setSubtitleGravity(int gravity) {
      mHeaderParams.subtitle.gravity = gravity;
      return toBuilder();
    }

    /**
     * 设置副标题视图背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setSubtitleBackgroundColor(@ColorInt int backgroundColor) {
      mHeaderParams.subtitle.backgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置副标题视图内边距
     * 格式：[start, top, end, bottom] px
     *
     * @param padding 边距
     */
    public B setSubtitlePadding(@Nullable @Size(4) int[] padding) {
      mHeaderParams.subtitle.padding = padding;
      return toBuilder();
    }

    /**
     * 设置副标题视图内边距
     *
     * @param padding 边距 px
     */
    public B setSubtitlePadding(@Px int padding) {
      return setSubtitlePadding(new int[]{padding, padding, padding, padding});
    }

    /**
     * 设置副标题视图内边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public B setSubtitlePadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setSubtitlePadding(new int[]{left, top, right, bottom});
    }

    /**
     * 设置副标题视图配置回调
     * 拥有绝对控制权的回调，它在其他属性配置结束后回调
     * 一般情况不要使用它，除非提供的现有配置属性不满足需求
     *
     * @param callback 配置回调
     */
    public B setSubtitleViewCallback(@Nullable ConfigViewCallback<SubtitleView> callback) {
      mHeaderParams.subtitle.callback = callback;
      return toBuilder();
    }

    //=============================================================================================//

    /**
     * 设置消极按钮视图文本
     *
     * @param text 文本
     */
    public B setNegativeButtonText(@Nullable CharSequence text) {
      mFooterParams.negative.text = text;
      mFooterParams.negative.textColor = 0xFF464646;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图文本
     *
     * @param text 文本
     */
    public B setPositiveButtonText(@Nullable CharSequence text) {
      mFooterParams.positive.text = text;
      mFooterParams.positive.textColor = 0xFF007AFF;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图文本
     *
     * @param text 文本
     */
    public B setNeutralButtonText(@Nullable CharSequence text) {
      mFooterParams.neutral.text = text;
      mFooterParams.neutral.textColor = 0xFF464646;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图文本字体大小 sp
     *
     * @param textSize 字体大小
     */
    public B setNegativeButtonTextSize(float textSize) {
      mFooterParams.negative.textSize = textSize;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图文本字体大小 sp
     *
     * @param textSize 字体大小
     */
    public B setPositiveButtonTextSize(float textSize) {
      mFooterParams.positive.textSize = textSize;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图文本字体大小 sp
     *
     * @param textSize 字体大小
     */
    public B setNeutralButtonTextSize(float textSize) {
      mFooterParams.neutral.textSize = textSize;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setNegativeButtonTextColor(@ColorInt int textColor) {
      mFooterParams.negative.textColor = textColor;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setPositiveButtonTextColor(@ColorInt int textColor) {
      mFooterParams.positive.textColor = textColor;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setNeutralButtonTextColor(@ColorInt int textColor) {
      mFooterParams.neutral.textColor = textColor;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图是否处于禁用状态
     *
     * @param disabled 是否处于禁用状态
     */
    public B setNegativeButtonDisabled(boolean disabled) {
      mFooterParams.negative.disabled = disabled;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图是否处于禁用状态
     *
     * @param disabled 是否处于禁用状态
     */
    public B setPositiveButtonDisabled(boolean disabled) {
      mFooterParams.positive.disabled = disabled;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图是否处于禁用状态
     *
     * @param disabled 是否处于禁用状态
     */
    public B setNeutralButtonDisabled(boolean disabled) {
      mFooterParams.neutral.disabled = disabled;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图禁用状态下的文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setNegativeButtonDisabledTextColor(@ColorInt int textColor) {
      mFooterParams.negative.disabledTextColor = textColor;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图禁用状态下的文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setPositiveButtonDisabledTextColor(@ColorInt int textColor) {
      mFooterParams.positive.disabledTextColor = textColor;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图禁用状态下的文本字体颜色 argb
     *
     * @param textColor 字体颜色
     */
    public B setNeutralButtonDisabledTextColor(@ColorInt int textColor) {
      mFooterParams.neutral.disabledTextColor = textColor;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图文本字体样式
     *
     * @param typeface 字体样式
     */
    public B setNegativeButtonTypeface(int typeface) {
      mFooterParams.negative.typeface = typeface;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图文本字体样式
     *
     * @param typeface 字体样式
     */
    public B setPositiveButtonTypeface(int typeface) {
      mFooterParams.positive.typeface = typeface;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图文本字体样式
     *
     * @param typeface 字体样式
     */
    public B setNeutralButtonTypeface(int typeface) {
      mFooterParams.neutral.typeface = typeface;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setNegativeButtonBackgroundColor(@ColorInt int backgroundColor) {
      mFooterParams.negative.backgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setPositiveButtonBackgroundColor(@ColorInt int backgroundColor) {
      mFooterParams.positive.backgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setNeutralButtonBackgroundColor(@ColorInt int backgroundColor) {
      mFooterParams.neutral.backgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图按下状态背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setNegativeButtonPressedBackgroundColor(@ColorInt int backgroundColor) {
      mFooterParams.negative.pressedBackgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图按下状态背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setPositiveButtonPressedBackgroundColor(@ColorInt int backgroundColor) {
      mFooterParams.positive.pressedBackgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图按下状态背景颜色 argb
     *
     * @param backgroundColor 背景颜色
     */
    public B setNeutralButtonPressedBackgroundColor(@ColorInt int backgroundColor) {
      mFooterParams.neutral.pressedBackgroundColor = backgroundColor;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图内边距
     * 格式：[start, top, end, bottom] px
     *
     * @param padding 边距
     */
    public B setNegativeButtonPadding(@Nullable @Size(4) int[] padding) {
      mFooterParams.negative.padding = padding;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图内边距
     *
     * @param padding 边距 px
     */
    public B setNegativeButtonPadding(@Px int padding) {
      return setNegativeButtonPadding(new int[]{padding, padding, padding, padding});
    }

    /**
     * 设置消极按钮视图内边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public B setNegativeButtonPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setNegativeButtonPadding(new int[]{left, top, right, bottom});
    }

    /**
     * 设置积极按钮视图内边距
     * 格式：[start, top, end, bottom] px
     *
     * @param padding 边距
     */
    public B setPositiveButtonPadding(@Nullable @Size(4) int[] padding) {
      mFooterParams.positive.padding = padding;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图内边距
     *
     * @param padding 边距 px
     */
    public B setPositiveButtonPadding(@Px int padding) {
      return setPositiveButtonPadding(new int[]{padding, padding, padding, padding});
    }

    /**
     * 设置积极按钮视图内边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public B setPositiveButtonPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setPositiveButtonPadding(new int[]{left, top, right, bottom});
    }

    /**
     * 设置中立按钮视图内边距
     * 格式：[start, top, end, bottom] px
     *
     * @param padding 边距
     */
    public B setNeutralButtonPadding(@Nullable @Size(4) int[] padding) {
      mFooterParams.neutral.padding = padding;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图内边距
     *
     * @param padding 边距 px
     */
    public B setNeutralButtonPadding(@Px int padding) {
      return setNeutralButtonPadding(new int[]{padding, padding, padding, padding});
    }

    /**
     * 设置中立按钮视图内边距
     *
     * @param left   左边距 px
     * @param top    上边距 px
     * @param right  右边距 px
     * @param bottom 下边距 px
     */
    public B setNeutralButtonPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
      return setNeutralButtonPadding(new int[]{left, top, right, bottom});
    }

    /**
     * 设置消极按钮视图延时可用
     *
     * @param delay 延时 s
     */
    public B setNegativeButtonDelay(int delay) {
      mFooterParams.negative.delay = delay;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图延时可用
     *
     * @param delay 延时 s
     */
    public B setPositiveButtonDelay(int delay) {
      mFooterParams.positive.delay = delay;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图延时可用
     *
     * @param delay 延时 s
     */
    public B setNeutralButtonDelay(int delay) {
      mFooterParams.neutral.delay = delay;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图延时禁用状态下文本格式
     * 其中须含有一个“%d”，用来显示倒计时
     *
     * @param delayFormat 延时禁用状态文本格式
     */
    public B setNegativeButtonDelayFormat(@Nullable String delayFormat) {
      mFooterParams.negative.delayFormat = delayFormat;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图延时禁用状态下文本格式
     * 其中须含有一个“%d”，用来显示倒计时
     *
     * @param delayFormat 延时禁用状态文本格式
     */
    public B setPositiveButtonDelayFormat(@Nullable String delayFormat) {
      mFooterParams.positive.delayFormat = delayFormat;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图延时禁用状态下文本格式
     * 其中须含有一个“%d”，用来显示倒计时
     *
     * @param delayFormat 延时禁用状态文本格式
     */
    public B setNeutralButtonDelayFormat(@Nullable String delayFormat) {
      mFooterParams.neutral.delayFormat = delayFormat;
      return toBuilder();
    }

    /**
     * 设置消极按钮视图配置回调
     * 拥有绝对控制权的回调，它在其他属性配置结束后回调
     * 一般情况不要使用它，除非提供的现有配置属性不满足需求
     *
     * @param callback 配置回调
     */
    public B setNegativeButtonViewCallback(@Nullable ConfigViewCallback<ButtonView> callback) {
      mFooterParams.negative.callback = callback;
      return toBuilder();
    }

    /**
     * 设置积极按钮视图配置回调
     * 拥有绝对控制权的回调，它在其他属性配置结束后回调
     * 一般情况不要使用它，除非提供的现有配置属性不满足需求
     *
     * @param callback 配置回调
     */
    public B setPositiveButtonViewCallback(@Nullable ConfigViewCallback<ButtonView> callback) {
      mFooterParams.positive.callback = callback;
      return toBuilder();
    }

    /**
     * 设置中立按钮视图配置回调
     * 拥有绝对控制权的回调，它在其他属性配置结束后回调
     * 一般情况不要使用它，除非提供的现有配置属性不满足需求
     *
     * @param callback 配置回调
     */
    public B setNeutralButtonViewCallback(@Nullable ConfigViewCallback<ButtonView> callback) {
      mFooterParams.neutral.callback = callback;
      return toBuilder();
    }

    //=============================================================================================//

    /**
     * 设置按钮视图点击监听器
     *
     * @param listener 监听器
     */
    public B setButtonOnClickListener(@Nullable OnClickButtonListener<D> listener) {
      mOnClickButtonListener = listener;
      return toBuilder();
    }
  }
}

